package net.wanho.advice;

import cn.hutool.json.JSONUtil;
import lombok.SneakyThrows;
import net.wanho.mapper.UserInfoMapper;
import net.wanho.po.OperLog;
import net.wanho.service.OperLogService;
import net.wanho.util.AddressUtil;
import net.wanho.util.CurrentUtil;
import net.wanho.util.ServletUtil;
import net.wanho.vo.R;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 *
 * 操作日志切面
 */
@Component
@Aspect
public class OperLogAspect {

    @Resource
    private OperLogService operLogService;
    @Resource
    private UserInfoMapper userInfoMapper;

    @Pointcut("@annotation(org.springframework.web.bind.annotation.PostMapping)" +
            "||@annotation(org.springframework.web.bind.annotation.PutMapping)" +
            "||@annotation(org.springframework.web.bind.annotation.DeleteMapping)")
    public void pc() {
    }

    @SneakyThrows
    @Around("pc()")
    public Object around(ProceedingJoinPoint joinPoint) {
        /**
         * 对于特定的post、put、delete请求，不记录日志
         */
        List<String> list = Arrays.asList("login","logout");
        if(list.contains(joinPoint.getSignature().getName())){
            return joinPoint.proceed();
        }


        HttpServletRequest request = ServletUtil.getRequest();
        int businessType = 0;
        switch (request.getMethod()) {
            case "POST":
                businessType = 1;
                break;
            case "PUT":
                businessType = 2;
                break;
            case "DELETE":
                businessType = 3;
                break;
        }

        OperLog operLog = new OperLog();
        operLog.setTitle(request.getRequestURI().split("/")[2]);  //  请求路径/warehouse/user/user-list
        operLog.setBusinessType(businessType);
        operLog.setMethod(joinPoint.getSignature().getName());
        operLog.setRequestMethod(request.getMethod());
        operLog.setOperatorType(1);
        operLog.setOperName(userInfoMapper.selectById(CurrentUtil.getUserId()).getUserName());
        operLog.setOperUrl(request.getRequestURL().toString());
        operLog.setOperIp(AddressUtil.getIpAddr(request));
        operLog.setOperLocation(AddressUtil.getLocationByIp(operLog.getOperIp()));
        operLog.setOperParam(Arrays.toString(joinPoint.getArgs()));
        operLog.setOperTime(new Date());

        Long start = System.currentTimeMillis();
        try {
            // 核心业务
            Object res = joinPoint.proceed();
            operLog.setJsonResult(JSONUtil.toJsonStr(res));
            operLog.setStatus(0);

            return res;
        } catch (Throwable e) {
            operLog.setJsonResult(JSONUtil.toJsonStr(R.error(e.getMessage())));
            operLog.setStatus(1);
            operLog.setErrorMsg(e.getMessage());
            throw new RuntimeException(e.getMessage());
        }finally {
            Long end = System.currentTimeMillis();
            operLog.setCostTime(end-start);

            System.out.println("********************************************************"+Thread.currentThread().getName());

            // 记录操作日志
            operLogService.add(operLog);
        }
    }

}